package com.wsd.common.controller;

import com.wsd.common.dto.UserEntityForm;
import com.wsd.common.entity.ResponseEntity;
import com.wsd.common.entity.UserEntity;
import com.wsd.common.entity.UserRedisEntity;
import com.wsd.common.entity.UserTokenEntity;
import com.wsd.common.service.LoginService;
import com.wsd.common.utils.HttpUtils;
import com.wsd.common.utils.JwtUtils;
import com.wsd.exception.RRException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/wx")
public class LoginController {

    @Resource
    private LoginService loginService;

    @Resource
    private JwtUtils jwtUtils;

    @Value("${wx.appId}")
    private String appId;

    @Value("${wx.secret}")
    private String secret;

    @Value("${wx.code2session}")
    private String codeOriginRequestUrl;

    // 拼接后的url
    private String requestUrl;

    @PostConstruct
    public void init() {
        requestUrl = codeOriginRequestUrl + "?grant_type=authorization_code&appid=" + appId + "&secret=" + secret + "&js_code=";
    }

    /**
     * 测试登录方法
     * @param token
     * @return
     */
    @GetMapping("/test/login/{token}")
    public ResponseEntity testLogin(@PathVariable String token) {
        if (token.equals("root") || token.equals("admin")) {
            UserTokenEntity userTokenEntity = new UserTokenEntity();
            userTokenEntity.setOpenId(token);

            UserEntity userEntity = (UserEntity) loginService.containsUser(userTokenEntity);
            return ResponseEntity.success("登录成功").put("userInfo", userEntity).put("token", jwtUtils.generateToken(userTokenEntity));
        }

        return ResponseEntity.error("用户不存在!");
    }

    /**
     * 判断用户是否授权
     * @param code code
     * @return 用户是否授权登录
     */
    @GetMapping("/login/{code}")
    public ResponseEntity login(@PathVariable("code") String code, HttpServletRequest request) {
        UserTokenEntity userTokenEntity = this.getOpenId(code);  // 通过临时code获取openID和unionID
        UserRedisEntity userRedisEntity = loginService.containsUser(userTokenEntity);  // 查询数据库中是否存在该用户

        if (Objects.isNull(userRedisEntity)) {  // 数据库中没用该用户
            return ResponseEntity.error();
        }

        UserEntity userEntity = (UserEntity) userRedisEntity;
        userEntity.setLoginIp(request.getRemoteAddr());
        loginService.updateLoginStatus(userEntity);  // 更新用户登录状态

        return ResponseEntity.success("登录成功").put("userInfo", userEntity).put("token", jwtUtils.generateToken(userTokenEntity));
    }

    /**
     * 保存用户信息
     * @param userEntityForm 用户信息封装对象
     * @param request 请求
     * @return 是否成功
     */
    @PostMapping("/save")
    public ResponseEntity save(@RequestBody UserEntityForm userEntityForm, HttpServletRequest request) {

        UserTokenEntity tokenEntity = this.getOpenId(userEntityForm.getCode());

        // 保存请求Ip地址
        userEntityForm.setLoginIp(request.getRemoteAddr());
        userEntityForm.setOpenId(tokenEntity.getOpenId());

        try {
            loginService.saveUser(userEntityForm);
            loginService.updateLoginStatus(userEntityForm);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.error(null);
        }

        // 用户个人信息保存成功，返回token
        return ResponseEntity.success().put("token", jwtUtils.generateToken(tokenEntity));
    }

    /**
     * 向微信服务器发送请求, 获取openId
     * @param code code
     * @return token
     */
    private UserTokenEntity getOpenId(String code) {
        if (Objects.equals("the code is a mock one", code)) {
            throw new RRException("appid和微信小程序开发工具所登陆用户管理的小程序清单不匹配");
        }

        String url = requestUrl + code;
        String response = HttpUtils.get(url);
        return UserTokenEntity.build(response);
    }
}